#include "mainwindow.h"
#include "scriptslist.h"
#include "textbox.h"
#include "appslist.h"
#include "utils.h"

#include <QShortcut>
#include <QAction>
#include <QtWidgets>
#include <QtCore>

#include <string>
#include <fstream>
#include <iostream>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    updateStyle();
    updateConnections();
}

void MainWindow::setCurrentList(std::string listName) {
    if (listName == "apps") {
        appsList->show();
        scriptsList->hide();
        appsList->redrawApps();
        textbox->setPlaceholderText("Apps...");
    } else if (listName == "scripts") {
        appsList->hide();
        scriptsList->show();
        scriptsList->redrawScripts();
        textbox->setPlaceholderText("Scripts...");
    }
}

void MainWindow::swapList() {
    if (not appsList->isHidden()) {
        appsList->hide();
        scriptsList->show();
        scriptsList->redrawScripts();
        textbox->setPlaceholderText("Scripts...");

    } else if (not scriptsList->isHidden()) {
        scriptsList->hide();
        appsList->show();
        appsList->redrawApps();
        textbox->setPlaceholderText("Apps...");
    }
}

std::string MainWindow::getUserInputArguments() {
    std::string inputedName;
    std::string userArgs;

    // get user arguments from text input
    userArgs = textbox->text().toUtf8().constData();
    if (userArgs != "") {
        inputedName = getFirstWordInString(userArgs);
        // remove item name from arguments
        userArgs = userArgs.substr(inputedName.length(), userArgs.length());
    }

    return userArgs;
}

void MainWindow::launch() {
    std::string itemName;
    std::string executeString;
    std::string inputedName;
    std::string userArgs;

    // if applist is not hidden
    if (not appsList->isHidden()) {
        // check count of items, if it 0 - exit emily
        if ( appsList->count() == 0 ) {
            std::exit(1);
        }

        // get name of current item
        itemName = appsList->currentItem()->text().toUtf8().constData();

        // get user arguments from text input
        userArgs = getUserInputArguments();

        // print item name and get execute string by item name
        std::cout << itemName << std::endl;
        executeString = appsList->apps[itemName];

    // if scriptlist is not hidden
    } else if (not scriptsList->isHidden()) {
        // check count of items, if it 0 - exit emily
        if ( scriptsList->count() == 0 ) {
            std::exit(1);
        }

        // get name of current item
        itemName = scriptsList->currentItem()->text().toUtf8().constData();

        // get user arguments from text input
        userArgs = getUserInputArguments();

        // print item name and get execute string by item name
        std::cout << itemName << std::endl;
        executeString = scriptsList->scripts[itemName];
    }

    // set execute string and arguments of app
    std::string execute = executeString;
    std::string params = "";

    // if execute string has spaces - split it and add text after first space to arguments
    if (executeString.find(" ") != std::string::npos){
        char sep = ' ';
        vector<string> out;
        split(executeString, sep, out);

        execute = out[0].c_str();
        out.erase(out.begin());

        for (const auto &arg : out) {
            params.append(" " + arg);
        }
    }

    // add user arguments to params
    params.append(userArgs);

    // print total execute string and arguments
    std::cout << execute << " *" << std::endl;
    std::cout << params << " *" << std::endl;

    // execute app, exit after complete
    isLaunching = true;
    hide();
    CreateProcess(execute.c_str(), params.c_str());
    std::exit(0);
}

void MainWindow::scrollUp() {
    if (not appsList->isHidden()) {
        int itemIndex = appsList->currentIndex().row();
        int maxIndex = 0;

        if (itemIndex > maxIndex) {
            appsList->setCurrentItem(appsList->item(itemIndex-1));
        }
        /*else {
            appsList->setCurrentItem(appsList->item(appsList->count()-1));
        }*/
    } else if (not scriptsList->isHidden()) {
        int itemIndex = scriptsList->currentIndex().row();
        int maxIndex = 0;

        if (itemIndex > maxIndex) {
            scriptsList->setCurrentItem(scriptsList->item(itemIndex-1));
        }
    }
}

void MainWindow::scrollDown() {
    if (not appsList->isHidden()) {
        int itemIndex = appsList->currentIndex().row();
        int maxIndex = appsList->count()-1;

        if (itemIndex < maxIndex) {
           appsList->setCurrentItem(appsList->item(itemIndex+1));
        }
        /*else {
            appsList->setCurrentItem(appsList->item(0));
        }*/
    } else if (not scriptsList->isHidden()) {
        int itemIndex = scriptsList->currentIndex().row();
        int maxIndex = scriptsList->count()-1;

        if (itemIndex < maxIndex) {
           scriptsList->setCurrentItem(scriptsList->item(itemIndex+1));
        }
    }
}

void MainWindow::completeExecutionName() {
    std::string itemName = "";

    if (!appsList->isHidden() && appsList->count() > 0) itemName = appsList->currentItem()->text().toStdString();
    if (!scriptsList->isHidden() && scriptsList->count() > 0) itemName = scriptsList->currentItem()->text().toStdString();

    std::string textboxText = textbox->text().toStdString();
    std::string textboxArgs = "";
    std::string fword = "";

    if  (textboxText.length() > 0) {
        fword = getFirstWordInString(textboxText);
        textboxArgs = textboxText.substr(fword.length(), textboxText.length());
    }

    std::string totalString = itemName + textboxArgs;

    textbox->setText(totalString.c_str());
}

void MainWindow::updateStyle() {
    //===Window settings===
    setWindowTitle("emily");

    QSize size = QSize(cfg.windowWidth, cfg.windowHeight);

    setMinimumSize(size);
    setMaximumSize(size);
    move(cfg.windowX, cfg.windowY);

    if (cfg.isPopup) {
        setWindowFlags(Qt::Popup);
    }

    setStyleSheet(("MainWindow { background: " + colorScheme.backgroundColor + "; }").c_str());
}

void MainWindow::updateConnections() {
    QShortcut *shortcut = new QShortcut(QKeySequence("Down"), this);
    connect(shortcut, &QShortcut::activated, this, &MainWindow::scrollDown);

    shortcut = new QShortcut(QKeySequence("Up"), this);
    connect(shortcut, &QShortcut::activated, this, &MainWindow::scrollUp);

    shortcut = new QShortcut(QKeySequence("Return"), this);
    connect(shortcut, &QShortcut::activated, this, &MainWindow::launch);

    shortcut = new QShortcut(QKeySequence("Enter"), this);
    connect(shortcut, &QShortcut::activated, this, &MainWindow::launch);

    shortcut = new QShortcut(QKeySequence("Tab"), this);
    connect(shortcut, &QShortcut::activated, this, &MainWindow::swapList);

    shortcut = new QShortcut(QKeySequence("Alt+f"), this);
    connect(shortcut, &QShortcut::activated, this, &MainWindow::completeExecutionName);

    shortcut = new QShortcut(QKeySequence("Escape"), this);
    connect(shortcut, &QShortcut::activated, this, []{ std::exit(0); });
}


